package io.admin.common.utils;

import lombok.extern.slf4j.Slf4j;
import com.google.common.io.Files;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Slf4j
public class FileUtil {
    public static final Long FILE_MAX_SIZE = 20971520L;
    private static String separatorChar = "\\";
    public static final String PNG = "png";
    public static final String JPG = "jpg";
    public static final String GIF = "gif";
    public static final String BMP = "bmp";
    public static final String JPEG = "jpeg";
    public static final String PDF = "pdf";
    public static final String DOC = "doc";
    public static final String DOCX = "docx";
    public static final String XLS = "xls";
    public static final String XLSX = "xlsx";
    public static final String PPT = "ppt";
    public static final String PPTX = "pptx";
    public static final String TXT = "txt";
    public static final String HTML = "html";
    public static final String ZIP = "zip";
    public static final String APK = "apk";
    private static final Map<String, String> MIME = new HashMap(40);
    private static final Map<String, String> FILE_TYPE_MAP;
    private static List<String> allowExt;

    public FileUtil() {
    }

    public static String getPk() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    public static List<byte[]> inputStreamToByte(InputStream fileInputStream) {
        if (fileInputStream == null) {
            return null;
        } else {
            List<byte[]> l = new ArrayList();

            try {
                byte[] b = new byte[1024];

                int len;
                while((len = fileInputStream.read(b)) != -1) {
                    byte[] newB = Arrays.copyOfRange(b, 0, len);
                    l.add(newB);
                }
            } catch (Exception var13) {
                log.error("inputStreamToByte error ", var13);
            } finally {
                try {
                    fileInputStream.close();
                } catch (IOException var12) {
                    log.error("fileInputStream.close() error ", var12);
                }

            }

            return l;
        }
    }

    public static String readContentFromFile(File objFile) throws Exception {
        BufferedReader styleB = new BufferedReader(new InputStreamReader(new FileInputStream(objFile), "utf-8"));
        String line = "";
        StringBuffer parseString = new StringBuffer("");

        while((line = styleB.readLine()) != null) {
            parseString.append(line);
        }

        if (styleB != null) {
            styleB.close();
        }

        return parseString.toString();
    }

    /** @deprecated */
    @Deprecated
    public static File getUniqueFile(String tmpFilePath, String ext) throws IOException {
        String fileName = getPk();
        getTempFolder(tmpFilePath);
        return new File(tmpFilePath, "" + fileName + "." + ext);
    }

    public static File getLocalUniqueFile(String ext) throws IOException {
        File tmpDir = Files.createTempDir();
        return new File(tmpDir, getPk() + "." + ext);
    }

    /** @deprecated */
    @Deprecated
    public static File getPortalZipFile(String tmpFilePath, String ext) throws IOException {
        String fileName = "portal-" + System.currentTimeMillis();
        getTempFolder(tmpFilePath);
        return new File(tmpFilePath, "" + fileName + ext);
    }

    public static File getTempSourceFile(String tmpFilePath) throws Exception {
        getTempFolder(tmpFilePath);
        return new File(tmpFilePath, "/source");
    }

    public static File getPortalNoteFile(String tmpFilePath) throws IOException {
        String fileName = "/source/note";
        getTempFolder(tmpFilePath);
        File result = new File(tmpFilePath, fileName);
        if (result.exists() && result.isFile()) {
            result.deleteOnExit();
        }

        return new File(tmpFilePath, fileName);
    }

    public static File getTempFolder() {
        return Files.createTempDir();
    }

    /** @deprecated */
    @Deprecated
    public static File getTempFolder(String tempFilePath) {
        File tempFile = new File(tempFilePath);
        if (!tempFile.exists()) {
            tempFile.mkdirs();
        }

        return tempFile;
    }

    public static File getTmpFile(String prefix, String suffix) throws IOException {
        Path path = java.nio.file.Files.createTempFile(prefix, suffix);
        return path.toFile();
    }

    public static File getTmpFolder(String prefix) throws IOException {
        Path path = java.nio.file.Files.createTempDirectory(prefix);
        return path.toFile();
    }

    public static String getExt(String fileName) {
        String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
        return ext.toLowerCase();
    }

    public static void forceDelete(String file) throws IOException {
        forceDelete(new File(file));
    }

    public static void forceDelete(File file) throws IOException {
        if (file.isDirectory()) {
            deleteDirectory(file);
        } else if (file.isFile()) {
            File tf = new File(file.getAbsolutePath());
            if (tf.isFile()) {
                tf.delete();
            }
        }

    }

    public static void deleteDirectory(String directory) throws IOException {
        deleteDirectory(new File(directory));
    }

    public static void deleteDirectory(File directory) throws IOException {
        if (directory.exists()) {
            cleanDirectory(directory);
            if (!directory.delete()) {
                throw new IOException("Directory " + directory + " unable to be deleted.");
            }
        }
    }

    public static void cleanDirectory(String directory) throws IOException {
        cleanDirectory(new File(directory));
    }

    public static void cleanDirectory(File directory) throws IOException {
        String message;
        if (!directory.exists()) {
            message = directory + " does not exist";
            throw new IllegalArgumentException(message);
        } else if (!directory.isDirectory()) {
            message = directory + " is not a directory";
            throw new IllegalArgumentException(message);
        } else {
            File[] files = directory.listFiles();

            for(int i = 0; i < files.length; ++i) {
                File file = files[i];
                forceDelete(file);
            }

        }
    }

    public static File writeContentToTXTFile(File objFile, List titleList, List<String> keyList, Map codeMap, List<Map<String, Object>> dataList) {
        FileWriter fw = null;
        BufferedWriter bw = null;

        try {
            fw = new FileWriter(objFile);
            bw = new BufferedWriter(fw);
            writeTitleInfo(bw, titleList);
            writeContentInfo(bw, keyList, codeMap, dataList);
        } catch (IOException var20) {
            log.error("文件没有找到", var20);
        } finally {
            if (null != bw) {
                try {
                    bw.flush();
                } catch (IOException var19) {
                    log.error("bw.flush() error", var19);
                }
            }

            if (null != fw) {
                try {
                    fw.close();
                } catch (IOException var18) {
                    log.error("fw.close() error", var18);
                }
            }

        }

        return null;
    }

    private static void writeContentInfo(BufferedWriter bw, List<String> keyList, Map codeMap, List<Map<String, Object>> dataList) throws IOException {
        for(int j = 0; j < dataList.size(); ++j) {
            Map dataMap = (Map)dataList.get(j);

            for(int i = 0; i < keyList.size(); ++i) {
                String key = (String)keyList.get(i);
                Object data = dataMap.get(key);
                String ifCode = (String)codeMap.get(key);
                if (null != ifCode && !"".equals(ifCode) && data != null) {
                    String codeid = data.toString();

                    try {
                        data = null;
                        if (null == data) {
                            data = dataMap.get(key);
                        }
                    } catch (Exception var12) {
                        System.out.println("码表转换出错，请确认key：" + key + " 对应的value值：" + data + " 为码表的值");
                        data = dataMap.get(key);
                    }
                }

                if (null == data) {
                    data = "";
                }

                bw.write(data.toString());
                bw.write(separatorChar);
            }

            bw.newLine();
        }

    }

    private static void writeTitleInfo(BufferedWriter bw, List titleList) throws IOException {
        for(int i = 0; i < titleList.size(); ++i) {
            String value = titleList.get(i).toString();
            bw.write(value);
            bw.write(separatorChar);
        }

        bw.newLine();
    }



    public static boolean isImage(String externalName) {
        return "png".equalsIgnoreCase(externalName) || "gif".equalsIgnoreCase(externalName) || "bmp".equalsIgnoreCase(externalName) || "jpg".equalsIgnoreCase(externalName) || "jpeg".equalsIgnoreCase(externalName);
    }



    public static boolean isPdf(String externalName) {
        return "pdf".equalsIgnoreCase(externalName);
    }

    public static boolean isOffice(String externalName) {
        if ("ppt".equalsIgnoreCase(externalName)) {
            return true;
        } else if ("xls".equalsIgnoreCase(externalName)) {
            return true;
        } else if ("xlsx".equalsIgnoreCase(externalName)) {
            return true;
        } else if ("doc".equalsIgnoreCase(externalName)) {
            return true;
        } else if ("docx".equalsIgnoreCase(externalName)) {
            return true;
        } else if ("pptx".equalsIgnoreCase(externalName)) {
            return true;
        } else if ("ppt".equalsIgnoreCase(externalName)) {
            return true;
        } else {
            return "txt".equalsIgnoreCase(externalName);
        }
    }


    public static List<File> getAllFileWithPath(File file, List<File> tempList, Boolean isCustom) throws Exception {
        File[] files = file.listFiles();
        if (files == null) {
            return tempList;
        } else {
            File[] var4 = files;
            int var5 = files.length;

            for(int var6 = 0; var6 < var5; ++var6) {
                File f = var4[var6];
                if (f.isDirectory()) {
                    if (isCustom || !"custom".equalsIgnoreCase(f.getName())) {
                        getAllFileWithPath(f, tempList, isCustom);
                    }
                } else if (!"note".equalsIgnoreCase(f.getName())) {
                    tempList.add(f);
                }
            }

            return tempList;
        }
    }

    public static void copyFolder(File src, File dest) throws IOException {
        int length;
        if (src.isDirectory()) {
            if (dest.exists()) {
                dest.delete();
            }

            dest.mkdir();
            String[] files = src.list();
            String[] var3 = files;
            int var4 = files.length;

            for(length = 0; length < var4; ++length) {
                String file = var3[length];
                File srcFile = new File(src, file);
                File destFile = new File(dest, file);
                copyFolder(srcFile, destFile);
            }
        } else {
            InputStream in = null;
            OutputStream out = null;

            try {
                in = new FileInputStream(src);
                out = new FileOutputStream(dest);
                byte[] buffer = new byte[1024];

                while((length = in.read(buffer)) > 0) {
                    out.write(buffer, 0, length);
                }
            } catch (IOException var19) {
                throw var19;
            } finally {
                if (null != in) {
                    try {
                        in.close();
                    } catch (IOException var18) {
                        log.error("in.close() error", var18);
                    }
                }

                if (null != out) {
                    try {
                        out.close();
                    } catch (IOException var17) {
                        log.error("out.close() error", var17);
                    }
                }

            }
        }

    }

    public static String generateCDNPath(String attachmentCategoryEnum, String companyIDOrMobilePortalID, String fileName) {
        return generateCDNPath(attachmentCategoryEnum, DateUtil.currentTimestamp(), companyIDOrMobilePortalID, fileName);
    }

    public static String generateCDNPath(String attachmentCategoryEnum, Timestamp createTime, String companyIDOrMobilePortalID, String fileName) {
        String yMd = DateUtil.format(createTime, "yyyy/MM/dd");
        String uniqueCode = getPk();
        if (null == companyIDOrMobilePortalID || "".equals(companyIDOrMobilePortalID.replaceAll(" ", ""))) {
            companyIDOrMobilePortalID = "10000";
        }

        return attachmentCategoryEnum + "/" + companyIDOrMobilePortalID + "/" + uniqueCode + "/" + yMd + "/" + fileName;
    }

    public static String getFileNameFormUrlPath(String path) {
        String result = null;
        if (StringUtils.isNotBlank(path)) {
            int index = path.lastIndexOf("/");
            if (index != -1) {
                result = path.substring(index + 1);
            }
        }

        return result;
    }

    public static String getTempFilePath() {
        return System.getProperty("java.io.tmpdir");
    }

    public static File getTempSourceFile() throws Exception {
        File file = new File(System.getProperty("java.io.tmpdir"));
        if (!file.isDirectory()) {
            file.mkdirs();
        }

        return new File(file, "/source");
    }

    public static void byteToFile(byte[] buf, File file) {
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;

        try {
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(buf);
        } catch (Exception var17) {
            log.error("byteToFile error:", var17);
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException var16) {
                }
            }

            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException var15) {
                }
            }

        }

    }

    public static String checkFileSuffix(InputStream is, String ext) {
        if (StringUtils.isEmpty(ext)) {
            log.info("文件后缀为空");
            return null;
        } else {
            String fileType = getFileType(is, ext);
            if (StringUtils.isEmpty(fileType)) {
                log.info("文件头类型扩展名为空");
                return null;
            } else if (!allowExt.contains(fileType)) {
                log.info("不允许上传文件类型扩展名=" + fileType);
                return fileType;
            } else if (checkDefferent(ext, fileType)) {
                log.info("文件头类型与实际不相同" + ext + "==" + fileType);
                return null;
            } else {
                return fileType;
            }
        }
    }

    public static boolean checkDefferent(String ext, String fileType) {
        if ((!"jpg".equals(ext.toLowerCase()) && !"jpeg".equals(ext.toLowerCase()) || !"jpg".equals(fileType.toLowerCase())) && !"jpeg".equals(fileType.toLowerCase())) {
            return !ext.toLowerCase().equals(fileType.toLowerCase());
        } else {
            return false;
        }
    }

    public static boolean checkFileSize(File file) {
        if (!file.exists()) {
            log.error(file.getName() + " 文件不存在");
            return false;
        } else {
            boolean check = FILE_MAX_SIZE > file.length();
            if (!check) {
                log.error(file.getName() + " 文件大小超出系统限制 20M");
            }

            return check;
        }
    }

    public static String getFileType(InputStream is, String ext) {
        String res = null;

        try {
            byte[] b = new byte[30];
            is.read(b, 0, b.length);
            String fileCode = bytesToHexString(b);
            System.out.println(fileCode);
            log.info("当前文件头=" + fileCode);
            Iterator<String> keyIter = FILE_TYPE_MAP.keySet().iterator();

            String key;
            do {
                if (!keyIter.hasNext()) {
                    return null;
                }

                key = (String)keyIter.next();
            } while(!key.toLowerCase().startsWith(fileCode.toLowerCase()) && !fileCode.toLowerCase().startsWith(key.toLowerCase()));

            res = (String)FILE_TYPE_MAP.get(key);
            log.info("FILE_TYPE_MAP类型=" + res);
            if (StringUtils.isNotEmpty(res)) {
                if ("office".equals(res)) {
                    if (!"doc".equals(ext) && !"xls".equals(ext) && !"ppt".equals(ext)) {
                        return null;
                    }
                    if (!"apk".equals(ext)) {
                        return null;
                    }
                    log.info("office具体类型" + ext);
                    return ext;
                }

                if ("officex".equals(res)) {
                    if (!"docx".equals(ext) && !"xlsx".equals(ext) && !"pptx".equals(ext)&& !"apk".equals(ext)) {
                        return null;
                    }

                    log.info("officex具体类型" + ext);
                    return ext;
                }
            }

            return res;
        } catch (FileNotFoundException var7) {
            var7.printStackTrace();
        } catch (IOException var8) {
            var8.printStackTrace();
        }

        return null;
    }

    private static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src != null && src.length > 0) {
            for(int i = 0; i < src.length; ++i) {
                int v = src[i] & 255;
                String hv = Integer.toHexString(v);
                if (hv.length() < 2) {
                    stringBuilder.append(0);
                }

                stringBuilder.append(hv);
            }

            return stringBuilder.toString();
        } else {
            return null;
        }
    }

    public static File getPortalNoteFile() throws IOException {
        String fileName = "/source/note";
        File file = new File(getTempFilePath());
        if (!file.isDirectory()) {
            file.mkdirs();
        }

        File result = new File(file, fileName);
        if (result.exists() && result.isFile()) {
            result.delete();
        }

        return new File(file, fileName);
    }

    public static String getContentType(String fileExt) throws Exception {
        String cType = "application/x-msdownload";
        if (fileExt != null && fileExt.trim().length() != 0) {
            String ext = fileExt;
            if (fileExt.startsWith(".")) {
                ext = fileExt.substring(1);
            }

            cType = (String)MIME.get(ext);
            if (cType == null) {
                cType = "application/x-msdownload";
            }

            return cType;
        } else {
            return cType;
        }
    }

    public static byte[] fileToByte(File file) {
        byte[] buffer = null;
        FileInputStream fis = null;
        ByteArrayOutputStream bos = null;

        try {
            fis = new FileInputStream(file);
            bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];

            int n;
            while((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }

            buffer = bos.toByteArray();
        } catch (FileNotFoundException var21) {
            log.error("FileTobyte FileNotFoundException:", var21);
        } catch (Exception var22) {
            log.error("FileTobyte error:", var22);
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (Exception var20) {
                }
            }

            if (fis != null) {
                try {
                    fis.close();
                } catch (Exception var19) {
                }
            }

        }

        return buffer;
    }

    static {
        MIME.put(".doc", "application/msword");
        MIME.put(".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
        MIME.put(".xls", "application/vnd.ms-poi");
        MIME.put(".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        MIME.put(".ppt", "application/vnd.ms-powerpoint");
        MIME.put(".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation");
        MIME.put(".pdf", "application/pdf");
        MIME.put(".key", "application/x-iwork-keynote-sffkey");
        MIME.put(".pages", "application/x-iwork-pages-sffpages");
        MIME.put(".numbers", "application/x-iwork-numbers-sffnumbers");
        MIME.put(".rtf", "application/rtf");
        MIME.put(".jpe", "image/jpeg");
        MIME.put(".jpeg", "image/jpeg");
        MIME.put(".jpg", "image/jpeg");
        MIME.put(".gif", "image/gif");
        MIME.put(".png", "image/png");
        MIME.put(".bmp", "image/bmp ");
        MIME.put(".tif", "image/tiff");
        MIME.put(".mp3", "audio/x-mpeg");
        MIME.put(".amr", "audio/amr");
        MIME.put(".aac", "audio/x-aac");
        MIME.put(".caf", "audio/x-caf");
        MIME.put(".wav", "audio/wav");
        MIME.put(".wma", "audio/x-ms-wma");
        MIME.put(".awb", "audio/amr-wb");
        MIME.put(".mid", "audio/midi");
        MIME.put(".midi", "audio/midi");
        MIME.put(".ra", "audio/x-pn-realaudio");
        MIME.put(".ram", "audio/x-pn-realaudio");
        MIME.put(".html", "text/html");
        MIME.put(".htx", "text/html");
        MIME.put(".htm", "text/html");
        MIME.put(".xml", "text/xml");
        MIME.put(".xsl", "text/xml");
        MIME.put(".xhtml", "application/xhtml+xml");
        MIME.put(".txt", "text/plain");
        MIME.put(".js", "text/javascript");
        MIME.put(".mp4", "video/mp4");
        MIME.put(".mpeg", "video/mpeg");
        MIME.put(".mpg", "video/mpeg");
        MIME.put(".avi", "video/avi");
        MIME.put(".wmv", "video/x-ms-wmv");
        MIME.put(".flv", "video/x-flv");
        MIME.put(".mov", "video/quicktime");
        MIME.put(".m4v", "video/x-m4v");
        MIME.put(".3gp", "video/3gpp");
        MIME.put(".exe", "application/x-msdownload");
        MIME.put(".apk", "application/vnd.android.package-archive");
        MIME.put(".swf", "application/x-shockwave-flash");
        MIME.put(".zip", "application/zip");
        MIME.put(".rar", "application/x-rar-compressed");
        FILE_TYPE_MAP = new HashMap<String, String>() {
            {
                this.put("FFD8FF", "jpg");
                this.put("89504E47", "png");
                this.put("47494638", "gif");
                this.put("49492A00", "tif");
                this.put("424D", "bmp");
                this.put("41433130", "dwg");
                this.put("38425053", "psd");
                this.put("7B5C727466", "rtf");
                this.put("3C3F786D6C", "xml");
                this.put("68746D6C3E", "html");
                this.put("44656C69766572792D646174653A", "eml");
                this.put("D0CF11E0", "office");
                this.put("5374616E64617264204A", "mdb");
                this.put("252150532D41646F6265", "ps");
                this.put("255044462D312E", "pdf");
                this.put("504b0304", "officex");
                this.put("AC9EBD8F", "qdf");
                this.put("57415645", "wav");
                this.put("41564920", "avi");
                this.put("2E524D46", "rm");
                this.put("000001BA", "mpg");
                this.put("000001B3", "mpg");
                this.put("6D6F6F76", "mov");
                this.put("3026B2758E66CF11", "asf");
                this.put("4D546864", "mid");
                this.put("464C560105", "flv");
                this.put("0000002066", "mp4");
                this.put("494433030000", "mp3");
                this.put("504b030414000000", "zip");
                this.put("52617221", "rar");
                this.put("1F8B08", "gz");
            }
        };
        allowExt = Arrays.asList("png", "jpg", "gif", "bmp", "jpeg", "pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "zip","apk");
    }
}
